﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;


namespace FindProxy
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
            openFileDialog1.InitialDirectory = Path.GetDirectoryName(Application.ExecutablePath);
            ServicePointManager.DefaultConnectionLimit = 150;
            ThreadPool.SetMaxThreads(300, 100);
            ThreadPool.SetMinThreads(100, 50);

            if (checkBox1.Checked)
            {
                button2_Click(null, null);
            }

        }

        private AutoResetEvent are = new AutoResetEvent(true);
        private bool autoRun;
        private bool complete = false;
        int currentIndex;
        private string currentURL;
        private DateTime endTime;
        private int failed = 0;
        //   string pageData;

        string ip = "";

        private bool jjj = true;
        private int launched = 0;
        private object launchedLock = new object();
        string patternIPAndPort = @"\d+\..+\..+?'\d+\d+";
        int port = 0;
        List<string> proxyList = new List<string>();
        Regex rex;
        private DateTime startTime;
        private int succ = 0;
        private System.Threading.Timer t;
        Thread th;
        private int timeoutcount = 0;
        private int total = 0;
        string uris;

        private int used = 0;

        private object usedLock = new object();
        private int usedProxyCount = 0;
        private int userdProxyCount;
        private List<string> visitUrls = new List<string>();
        private WebDownload wc;

        private void button1_Click(object sender, EventArgs e)
        {
            frmIpConvert f = new frmIpConvert();
            f.Show();
        }
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                startTime = DateTime.Now;
                autoRun = checkBox1.Checked;
                succ = 0;
                failed = 0;
                uris = textBox1.Text;
                userdProxyCount = int.Parse(txtCount.Text);
                if (userdProxyCount == 0)
                {
                    userdProxyCount = int.MaxValue;
                }
                getProxy();

                th = new Thread(new ThreadStart(f)) { IsBackground = true };
                th.Start();

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {

            }

        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox2.Text = openFileDialog1.FileName;

            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                Process po = new Process();
                var pi = new ProcessStartInfo("notepad", textBox2.Text);
                po.StartInfo = pi;
                po.Start();
            }
            catch (Exception)
            {
                throw;
            }

        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = openFileDialog1.FileName;

            }
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            th.Abort();
        }
        void c(object o)
        {
            this.Close();
            Application.Exit();
        }




        private void DownloadString(string uri, int i)
        {

            wc = new WebDownload() { Timeout = 15000 };

            //    wc.BaseAddress = uri;
            currentIndex = i + 1;
            string[] s = proxyList[i].Split(new char[] { ':' });
            ip = s[0];
            port = int.Parse(s[1]);

            var proxy = new WebProxy(ip, port);

            proxy.BypassProxyOnLocal = false;
            WebRequest.DefaultWebProxy = proxy;
            wc.Credentials = CredentialCache.DefaultCredentials;
            wc.Proxy = proxy;
            lock (launchedLock)
            {
                launched++;
            }
            try
            {
                // wc.DownloadStringAsync(new Uri(uri));

                wc.GetStringAsync(new Uri(uri));
                wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);

            }
            catch (Exception ex)
            {

            }
        }
        void f()
        {
            try
            {
                foreach (var visitUrl in visitUrls)
                {
                    currentURL = visitUrl;
                    are.WaitOne(300 * 1000);
                    for (int i = usedProxyCount; i < proxyList.Count; i++)
                    {
                        if (userdProxyCount != int.MaxValue)//有限制,则平均分配
                        {
                            if (i >= usedProxyCount + proxyList.Count / visitUrls.Count)
                            {
                                usedProxyCount = i + 1;
                                break;
                            }
                        }
                        are.Reset();
                        DownloadString(currentURL, i);
                        //ThreadPool.QueueUserWorkItem(
                        //    DownloadString, new DownloadEventArgs(currentURL, i));
                    }
                }
                complete = true;


            }
            catch (Exception ex)
            {

            }

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (th != null)
            {
                th.Abort();
            }
            endTime = DateTime.Now;
            var sp = endTime - startTime;
            string s;
            try
            {
                s = string.Format("\r\n共访问{0} \r\n{1}\r\n用时:{2},速度{3}/s", succ, DateTime.Now, sp, succ / sp.TotalSeconds);
            }
            catch (Exception)
            {

                s = string.Format("\r\n共访问{0} \r\n{1}\r\n用时:{2},速度{3}/s", succ, DateTime.Now, sp, 0);
            }
            FindProxy.Properties.Settings.Default.Save();
            File.AppendAllText("log.txt", s);


        }
        void getProxy()
        {
            proxyList.Clear();
            visitUrls.Clear();
            string data = "";
            using (FileStream fs = new FileStream(textBox2.Text, FileMode.Open, FileAccess.Read))
            {

                using (StreamReader sr = new StreamReader(fs))
                {
                    string[] s;
                    data = sr.ReadToEnd();
                    if (data != "" && data != null)
                    {

                        rex = new Regex(@"(\d+\.\d+\.\d+\.\d+:\d+)");

                        MatchCollection mc = rex.Matches(data);
                        foreach (Match m in mc)
                        {
                            proxyList.Add(m.ToString());
                        }
                        total = proxyList.Count;
                    }

                }

            }
            using (FileStream fs = new FileStream(textBox1.Text, FileMode.Open, FileAccess.Read))
            {
                using (StreamReader sr = new StreamReader(fs))
                {

                    data = sr.ReadLine();
                    while (data != "" && data != null)
                    {
                        visitUrls.Add(data);
                        data = sr.ReadLine();
                    }
                }
            }

        }

        private void textBox1_Click(object sender, EventArgs e)
        {
            textBox1.SelectAll();
        }
        void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            lock (usedLock)
            {
                used++;
            }
            var w = sender as WebDownload;
            if (e.Cancelled)
            {
                timeoutcount++;
            }
            else
            {
                if (e.Error == null)
                {
                    succ++;
                }
                else
                {
                    failed++;
                }
            }
            w.Dispose();
            try
            {
                this.Invoke(
             (Action)(() =>
              {

                  toolStripStatusLabel1.Text =
                        string.Format("成功:{0} 失败:{1},超时:{2} 全部{3} ,已用 {4} ",
                        succ, failed, timeoutcount, total, used);
              }
              )

              );
            }
            catch (Exception)
            {


            }

            lock (usedLock)
            {
                lock (launchedLock)
                {
                    if (used == launched)
                    {
                        are.Set();
                    }
                }

            }
            if (autoRun)
            {
                if (complete)
                {

                    if (used >= launched)
                    {
                        try
                        {
                            this.Invoke(

                         (Action)(
                                      () =>
                                      {
                                          Close();
                                      }
                 ));
                        }
                        catch (Exception)
                        {

                        }

                    }

                }
            }

        }

        private delegate void ccccc(object o);
        delegate void Close();

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                Application.Exit();
            }
            catch (Exception ex)
            {
                MessageBox.Show("关闭出错");
            }

        }


    }
}
